package org.TCC_NOVO.dao;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

public abstract class JPADAO<T> implements DAO<T>
{
	private JPAUtil jpaUtil;
	private Class<T> classe;
	private Method getId;
	
	public JPADAO(Class<T> classe) throws Exception 
	{
		try 
		{ 
			JPAUtil.inicializar("sapi"); // TODO precisa haver uma inicializacao centralizada !!! Nao deveriamos mais contar com essa inicializacao !!!
		} 
		catch (Exception e) 
		{
			System.out.println(getClass().getSimpleName() + ":");
			e.printStackTrace(); // nao podemos esconder essa excecao
			
			throw e;
		}
		
		this.jpaUtil = JPAUtil.getInstance();
		this.classe = classe;
		
		getId = classe.getMethod("getId");
	}
	
	protected final JPAUtil getJpaUtil() 
	{
		return jpaUtil;
	}
	
	@Override
	public T ler(long id) throws Exception 
	{
		return jpaUtil.ler(classe, id);
	}
	
	@Override
	public List<T> listarTodos() throws Exception 
	{
		return jpaUtil.listarTodos(classe);
	}
	
	@Override
	public void excluir(T objeto) throws Exception 
	{
		jpaUtil.excluir(objeto);
	}
	
	protected final List<T> listarConsultaNomeada(String nome)
	{
		return listarConsultaNomeada(nome, -1, -1, null);
	}
	
	protected final List<T> listarConsultaNomeada(String nome, Map<String, Object> parametros)
	{
		return listarConsultaNomeada(nome, -1, -1, parametros);
	}

	protected final List<T> listarConsultaNomeada(String nome, long registroInicial, long registroFinal)
	{
		return listarConsultaNomeada(nome, registroInicial, registroFinal, null);
	}
	
	protected final List<T> listarConsultaNomeada(String nome, long registroInicial, long registroFinal, Map<String, Object> parametros)
	{
		return jpaUtil.listarConsultaNomeada(nome, registroInicial, registroFinal, parametros);
	}
	
	protected final T consultaNomeada(String consultaNomeada) throws Exception
	{
		return consultaNomeada(consultaNomeada, null);
	}
	
	protected final T consultaNomeada(String consultaNomeada, Map<String, Object> parametros) throws Exception
	{
		return (T)(jpaUtil.consultaNomeada(consultaNomeada, parametros));
	}	
	
	protected final Object executarConsulta(String sql)
	{
		return executarConsulta(sql, -1, -1, null);
	}
	
	protected final Object executarConsulta(String sql, Map<String, Object> parametros)
	{
		return executarConsulta(sql, -1, -1, parametros);
	}
	
	protected final Object executarConsulta(String sql, long registroInicial, long registroFinal)
	{
		return executarConsulta(sql, registroInicial, registroFinal, null);
	}
	
	protected final Object executarConsulta(String sql, long registroInicial, long registroFinal, Map<String, Object> parametros)
	{
		return jpaUtil.executarConsulta(sql, registroInicial, registroFinal, parametros);
	}
	
	public final void gravar(T objeto) throws Exception 
	{		
		long id = (Long) getId.invoke(objeto);
		
		if (id == 0) jpaUtil.incluir(objeto);
		else jpaUtil.alterar(objeto);
	};	
	
}
